﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;

namespace OF.Common
{
    /// <summary>
    /// 文件名称：sql检测类
    /// </summary>
    public class SqlKey
    {
        //检测到注入后的处理方式:   0:仅警告；1：警告+记录；2：警告+自定义错误页面；3：警告+记录+自定义错误页面
        private const int _type = 3;
        private const string errRedirectPage = "index.aspx";

        //过滤特征字符
        private const string StrKeyWord = @"select|insert|delete|from|count(|drop table|update|truncate|asc(|mid(|char(|xp_cmdshell|exec|master|net local group administrators|net user|script|or|and";
        private const string StrRegex = @",|[|]|{|}|%|'|!|<|>";
        private const string StrRegex_LoginName = @"-|,|(|)|[|]|{|}|%|'|!";
        private const string strKey = @"[|]|{|}|%|'|<|>";
        private const string StrHttp = @",|[|]|{|}|%|'|!|<|>";

        private HttpRequest request;
        public SqlKey(System.Web.HttpRequest _request)
        {
            this.request = _request;
        }

        ///<summary>
        ///检查文本输入字符串中是否包含Sql注入关键字
        ///不验证(),;-!
        /// <param name="_key">被检查的字符串</param>
        /// <returns>如果包含注入true;否则返回false</returns>
        ///</summary>
        public static bool CheckText(string _key)
        {
            string[] pattenString = StrKeyWord.Split('|');
            string[] pattenRegex = strKey.Split('|');
            foreach (string sqlParam in pattenString)
            {
                if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
                {
                    return true;
                }
            }
            foreach (string sqlParam in pattenRegex)
            {
                if (_key.Contains(sqlParam))
                {
                    return true;
                }
            }
            return false;
        }

        private string RelaceSingleQuotes(string _url)
        {
            string URL = _url.Replace("'", "单引号");
            return URL;
        }

        ///<summary>
        /// 特征字符
        ///</summary>
        public static string KeyWord
        {
            get
            {
                return StrKeyWord;
            }
        }
        ///<summary>
        /// 特征符号
        ///</summary>
        public static string RegexString
        {
            get
            {
                return StrRegex;
            }
        }

        ///<summary>
        ///检查字符串中是否包含Sql注入关键字
        /// <param name="_key">被检查的字符串</param>
        /// <returns>如果包含注入true;否则返回false</returns>
        ///</summary>
        public static bool CheckKeyWord(string _key)
        {
            string[] pattenString = StrKeyWord.Split('|');
            string[] pattenRegex = StrRegex.Split('|');
            foreach (string sqlParam in pattenString)
            {
                if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
                {
                    return true;
                }
            }
            foreach (string sqlParam in pattenRegex)
            {
                if (_key.Contains(sqlParam))
                {
                    return true;
                }
            }
            return false;
        }

        ///<summary>
        ///检查URL中是否包含Sql注入
        /// <param name="_request">当前HttpRequest对象</param>
        /// <returns>如果包含注入true;否则返回false</returns>
        ///</summary>
        public bool CheckRequestQuery()
        {
            if (request.QueryString.Count > 0)
            {
                foreach (string sqlParam in this.request.QueryString)
                {
                    if (sqlParam == "__VIEWSTATE") continue;
                    if (sqlParam == "__EVENTVALIDATION") continue;
                    if (CheckKeyWord(request.QueryString[sqlParam].ToLower()))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        ///<summary>
        ///检查提交的表单中是否包含Sql注入
        /// <param name="_request">当前HttpRequest对象</param>
        /// <returns>如果包含注入true;否则返回false</returns>
        ///</summary>
        public bool CheckRequestForm()
        {
            if (request.Form.Count > 0)
            {
                foreach (string sqlParam in this.request.Form)
                {
                    if (sqlParam == "__VIEWSTATE") continue;
                    if (sqlParam == "__EVENTVALIDATION") continue;
                    if (CheckKeyWord(request.Form[sqlParam]))
                    {
                        return true;
                    }
                }
            }
            return false;
        }


        ///<summary>
        ///检查登录账号是否包含Sql注入关键字
        /// <param name="_key">被检查的字符串</param>
        /// <returns>如果包含注入true;否则返回false</returns>
        ///</summary>
        public static bool CheckLoginName(string _key)
        {
            string[] pattenString = StrKeyWord.Split('|');
            string[] pattenRegex = StrRegex_LoginName.Split('|');
            foreach (string sqlParam in pattenString)
            {
                if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
                {
                    return true;
                }
            }
            foreach (string sqlParam in pattenRegex)
            {
                if (_key.Contains(sqlParam))
                {
                    return true;
                }
            }
            return false;
        }

        ///<summary>
        ///检查字符串中是否包含Sql注入关键字
        /// <param name="_key">被检查的字符串</param>
        /// <returns>返回字符串</returns>
        ///</summary>
        public static string CheckWord(string _key)
        {
            string[] pattenString = StrKeyWord.Split('|');
            string[] pattenRegex = StrRegex.Split('|');
            foreach (string sqlParam in pattenString)
            {
                if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
                {
                    for (int i = 0; i < pattenString.Length; i++)
                    {
                        if (_key.IndexOf(pattenString[i].Trim()) >= 0)
                            _key = _key.Replace(pattenString[i].Trim(), " ");
                    }
                }
            }
            foreach (string sqlParam in pattenRegex)
            {
                if (_key.Contains(sqlParam))
                {
                    for (int i = 0; i < pattenRegex.Length; i++)
                    {
                        if (_key.IndexOf(pattenRegex[i].Trim()) >= 0)
                            _key = _key.Replace(pattenRegex[i].Trim(), " ");
                    }
                }
            }
            return _key;
        }

        public static bool CheckHttp(string _key)
        {
            string[] pattenString = StrKeyWord.Split('|');
            string[] pattenRegex = StrHttp.Split('|');
            foreach (string sqlParam in pattenString)
            {
                if (_key.Contains(sqlParam + " ") || _key.Contains(" " + sqlParam))
                {
                    return true;
                }
            }
            foreach (string sqlParam in pattenRegex)
            {
                if (_key.Contains(sqlParam))
                {
                    return true;
                }
            }
            return false;
        }
    }
}
